package cn.wangxl.group.rpc.server;

import cn.wangxl.group.rpc.handler.RequestHandler;
import cn.wangxl.group.rpc.protocol.Protocol;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Deacription BioRpcServer
 * @Author 20112128
 * @Date 2020/9/23 11:23
 **/
public class BioRpcServer extends RpcServer{

    private volatile boolean run;

    private RequestHandler requestHandler;

    public BioRpcServer(RequestHandler requestHandler, int port, Protocol protocol) {
        this.requestHandler = requestHandler;
        setPort(port);
        setProtocol(protocol);
    }

    @Override
    public void start() {
        run = true;
        try {
            // 1.绑定监听端口
            ServerSocket ss = new ServerSocket(getPort());
            System.out.println("启动BIO server，监听端口：" + getPort());
            // 2.处理请求
            while (run) {
                // 等待接口请求创建套接字，此方法为阻塞；
                Socket socket = ss.accept();
                System.out.println("接收到RPC请求，准备处理");
                // 伪异步处理
                ExecutorService es = Executors.newFixedThreadPool(10);
                es.execute(new ServerHandler(socket,requestHandler));
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }

        System.out.println("BIO服务暂停");
    }

    static class ServerHandler implements Runnable{

        private Socket socket;

        private RequestHandler requestHandler;

        public ServerHandler(Socket socket,RequestHandler requestHandler) {
            this.socket = socket;
            this.requestHandler = requestHandler;
        }

        @Override
        public void run() {
            InputStream in = null;
            OutputStream out = null;
            try {
                in = socket.getInputStream();
                out = socket.getOutputStream();
                System.out.println(in.available());
                byte[] requestData = null;
                if(in.available()>0){
                    requestData = new byte[in.available()];
                    in.read(requestData);
                }
                byte[] responseData = requestHandler.handleRequest(requestData);
                out.write(responseData);
                out.flush();

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                in = null;
                out = null;
                socket = null;
            }
        }
    }

    @Override
    public void stop() {
        this.run = false;
    }
}
